package com.oracle.application.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oracle.application.entity.Address;
import com.oracle.application.entity.Orderitems;
import com.oracle.application.entity.Orders;
import com.oracle.application.entity.vo.*;
import com.oracle.application.mapper.AddressMapper;
import com.oracle.application.mapper.OrderitemsMapper;
import com.oracle.application.mapper.OrdersMapper;
import com.oracle.application.service.IOrdersService;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisCluster;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author qhy
 * @since 2021-06-24
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    public DirectExchange  orderDirectExchange;

    @Autowired
    private AddressMapper addressMapper;

    @Autowired
    private OrderitemsMapper orderitemsMapper;

    @Autowired
    private OrdersMapper ordersMapper;

    //创建一个订单确认的token值
    //获取地址信息
    //所选购物车信息,创建订单详细内容
    //计算参考总价
    @Override
    public OrderConfirmVo creareOrderConfirm(List<CartVo> cartVos) {
        String orderTokenValue = UUID.randomUUID().toString().replace("-", "");


        List<Address> addresses = this.addressMapper.selectList(null);

        List<AddressVo> addressVoList = new ArrayList<>();
        AddressVo addressVo = null;
        for (Address address1 : addresses) {
            addressVo = new AddressVo();
            BeanUtils.copyProperties(address1, addressVo);
            addressVoList.add(addressVo);
        }


        List<Orderitems> orderitemsList = new ArrayList<>();
        List<OrderitemsVo> orderitemsVoList = new ArrayList<>();
        Orderitems orderitems = new Orderitems();
        for (CartVo car :cartVos) {
            orderitems = new Orderitems();
            orderitems.setSkusn(car.getSkusn());
            orderitems.setSkuname(car.getSkuname());
            orderitems.setImage(car.getImage());
            orderitems.setNum(car.getNum());
            orderitems.setPrice(car.getPrice());
            orderitemsList.add(orderitems);
        }

        OrderitemsVo orderitemsVo = null;
        for (Orderitems vo : orderitemsList) {
            orderitemsVo = new OrderitemsVo();
            BeanUtils.copyProperties(vo, orderitemsVo);
            orderitemsVoList.add(orderitemsVo);
        }

        BigDecimal totalPrice = new BigDecimal("0.0");
        for (OrderitemsVo vo : orderitemsVoList) {
            totalPrice = totalPrice.add(vo.getPrice().multiply(new BigDecimal(vo.getNum())));
        }
        System.out.println(totalPrice.setScale(2, BigDecimal.ROUND_DOWN));

        final String orderTokenKey = "pay:ordertoken:" + 1;
        this.redisTemplate.boundValueOps(orderTokenKey).set(orderTokenValue);

        String payMethod = "在线支付-支付宝支付";
        OrderConfirmVo orderConfirmVo = new OrderConfirmVo();
        orderConfirmVo.setAddressVoList(addressVoList);
        orderConfirmVo.setOrderToken(orderTokenValue);
        orderConfirmVo.setPayMethed(payMethod);
        orderConfirmVo.setTotalPrice(totalPrice.setScale(2, BigDecimal.ROUND_DOWN));
        orderConfirmVo.setOrderitemsVoList(orderitemsVoList);
        return orderConfirmVo;
    }


    @Override
    public Map<String,Object> submitOrder(OrderSbumitVo orderSbumitVo)throws Exception {
        Map<String,Object> rMap=new HashMap<>();
        final String orderTokenKey = "pay:ordertoken:" + 1;
        String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
        //lua脚本方式释放锁
        System.out.println(orderTokenKey+"=================1");
        Long result = this.redisTemplate.execute(new RedisCallback<Long>() {

            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                Object nativeConnection = connection.getNativeConnection();
                System.out.println(orderTokenKey+"=================1.3");
                // 集群模式
                if (nativeConnection instanceof JedisCluster) {
                    System.out.println(orderTokenKey+"=================1.2");
                    return (Long) ((JedisCluster) nativeConnection).eval(script, Arrays.asList(orderTokenKey), Arrays.asList(orderSbumitVo.getOrderToken()));
                }

                return null;
            }

        });
        System.out.println(orderTokenKey+"=================1.4");
        if (result==null||result==0){
            rMap.put("code",500);
            return  rMap;
        }
        System.out.println(orderTokenKey+"=================1.5");
        try {
            System.out.println(orderTokenKey+"=================2");
            Orders orders = new Orders();
            Address address = this.addressMapper.selectById(orderSbumitVo.getAddreddVoId());
            orders.setAddress(address.getAddress());
            orders.setArea(address.getArea());
            orders.setPhone(address.getPhone());
            orders.setZipcode("100231");
            orders.setConsigenn(address.getConsignee());
            orders.setCreatedate(LocalDateTime.now());
            orders.setModifydate(LocalDateTime.now());
            orders.setExpirtdate(orders.getCreatedate().plusMinutes(30));
            orders.setOrderstatus(0);
            orders.setMember(1);
            orders.setPaystatus(0);
            orders.setPaymethod(orderSbumitVo.getPayMethed());
            System.out.println("payMethod:->>>>>>>>>>>>>>>>>>>>" + orderSbumitVo.getPayMethed());
            //购物车信息[sku 名称 单价 购买数量]信息  变为订单明细信息

            List<Orderitems> orderitemsList = orderSbumitVo.getOrderitemsVoList().stream().map(orderitemsVo -> {
                Orderitems orderitems = new Orderitems();
                BeanUtils.copyProperties(orderitemsVo, orderitems);
                return orderitems;
            }).collect(Collectors.toList());

            BigDecimal totalPrice = new BigDecimal("0.0");
            //计算总价
            for (Orderitems orderitems : orderitemsList) {
                totalPrice = totalPrice.add(orderitems.getPrice().multiply(new BigDecimal(orderitems.getNum())));
            }

            orders.setTotalprice(totalPrice);
            orders.setOrdersn(IdWorker.getTimeId());

            //保存订单
            this.ordersMapper.insert(orders);

            orderitemsList.stream().forEach(orderitems -> orderitems.setOrders(orders.getId()));
            for (Orderitems orderitems : orderitemsList) {
                orderitems.setOrders(orders.getId());
                this.orderitemsMapper.insert(orderitems);
            }
            OrdersVo ordersVo = new OrdersVo();

            BeanUtils.copyProperties(orders, ordersVo);
            this.amqpTemplate.convertAndSend(this.orderDirectExchange.getName(),"order.create",JSONObject.toJSONString(ordersVo));
            //根据用户获取购物车服务  通过购物车
            rMap.put("data", ordersVo);
        }catch (Exception ex){
            throw ex;
        }
        System.out.println(orderTokenKey+"=================3");
        return rMap;
    }

    @Override
    public int updateOrderSatus(String orderSn) {
        int i = this.ordersMapper.updateOrderStatus(orderSn);
        return i;
    }

    public static void main(String[] args) {
        List<Address> addresses= new ArrayList<>();
        Address address = new Address();
        address.setAddress("123123");
        address.setArea("北京");
        address.setPhone("123123");
        addresses.add(address);

        List<AddressVo> addressVoList=new ArrayList<>();
        AddressVo addressVo=null;
        for (Address address1:addresses) {
            addressVo=new AddressVo();
            BeanUtils.copyProperties(address1,addressVo);
            addressVoList.add(addressVo);
        }


        List<Orderitems> orderitemsList=new ArrayList<>();
        Orderitems orderitems = new Orderitems();
        orderitems.setNum(20);
        orderitems.setPrice(new BigDecimal("200.20"));
        orderitemsList.add(orderitems);

        List<OrderitemsVo> orderitemsVoList=new ArrayList<>();
        OrderitemsVo orderitemsVo=null;
        for (Orderitems vo:orderitemsList) {
            orderitemsVo = new OrderitemsVo();
            BeanUtils.copyProperties(vo,orderitemsVo);
            orderitemsVoList.add(orderitemsVo);
        }

        BigDecimal totalPrice = new BigDecimal("0.0");
        for (OrderitemsVo vo:orderitemsVoList) {
            totalPrice=totalPrice.add(vo.getPrice().multiply(new BigDecimal(vo.getNum())));
        }
        System.out.println("总价为:"+totalPrice);
    }

}
